<?php

namespace App\Service\VendorClient\ShopNiCang;


use Service\AppService\IdService;
use App\Service\Code\Normal;
use App\Service\TaskServer\TaskWorker;

/**
 * 妮仓 WMS (金华保税仓)
 */
class ShopNiCangApiClient
{
    private static $instance;
    protected $clientConfig;

    /**
     */
    public static function instance()
    {
        if (empty(self::$instance)) {
            self::$instance = new static();
        }

        return self::$instance;
    }

    /**
     * 初始参数
     * @param  $collection
     */
    public function __construct($apiBody = [])
    {
        $this->clientConfig = $apiBody;
    }

    /**
     * CURL请求
     * @param array $param
     * @return array
     */
    public function execute($param = [])
    {
        $data=[
            'partner'=>$this->clientConfig['partner'],
            'method'=>$this->clientConfig[$param['method']],
            'signType'=>'1',
            'timestamp'=>time(),
            'content'=>$param['data'],
        ];
        $data['sign']=$this->getSign($data);
        $url = $this->clientConfig['baseurl'];
        $parameter = [
            [
                'tag'       => 'ShopNiCang_'.$param['method'],
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $data,
                'method'    => 'post',
                'format'    => 'json',
                'header'    => [],
            ],
        ];

        if( in_array($param['method'],['queryGoods','queryStock']) ) {
            $resTask = TaskWorker::instance()->addTask($parameter,'handleDiableTask');
        } else {
            $resTask = TaskWorker::instance()->addTask($parameter);
        }
        $resTask    = current($resTask);
        $resHttp    = @json_decode($resTask['response']['result'], true);
        $errorMsg = $resHttp['msg']??'请求失败';
        if( isset($resHttp['code']) && $resHttp['code'] == 200 ) {
            return Normal::returnCode(Normal::SUC,"操作成功",$resHttp);
        }
        return Normal::returnCode(Normal::FAIL,$errorMsg);

    }

    /**
     * 取消订单
     */
    public function cancelOrder( $params = [] )
    {
        if( empty($params['supplierOrder']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder");
        }
        if( empty($params['order']) ) {
            return Normal::returnCode(Normal::FAIL,"except param order");
        }
        $data = [
            'cancel'=>[
                'orderNo' => $params['supplierOrder']['order_sn'],
                'reason'=> $params['order']['exceptReason'] ?? '不想要了'
            ]
        ];

        $requestParam = [
            'method'    => 'orderCancel',
            'data'      => $data
        ];
        $res=$this->execute($requestParam);
        if ($res != Normal::SUC && strpos($res['msg'],'已递交取消，请勿重复递交')){
            $res['code']=Normal::SUC;
        }
        return $res;
    }

    /**
     * 获取签名
     * @param array $param
     */
    public function getSign($param)
    {
        $str=$param['partner'].$param['method'].$param['timestamp'].json_encode($param['content'],320).$this->clientConfig['secret'];
        return strtoupper(md5($str));
    }

    /**
     * 商品列表
     */
    public function queryGoodsList($param=[])
    {
        $requestParam = [
            'method'    => 'queryGoods',
            'data'   => [
                'pageNum'=> $param['page']??1,
                'pageSize'=>$param['limit']??20,
                "reqSupp"=>$param['req_supp']??'YXGJ'
            ]
        ];
        $response=$this->execute($requestParam);
        if ($response['code']!=Normal::SUC){
            return $response;
        }
        $skuNos=array_column($response['data']['rs']['pageList'],'PROD');
        if ($skuNos){
            $stockList=$this->goodsQueryStock($skuNos);
            foreach ($response['data']['rs']['pageList'] as &$v){
                $v['stock']=$stockList['data'][$v['PROD']]??0;
            }
        }
        return $response;
    }

    /**
     * 商品库存
     */
    public function goodsQueryStock($skuNos)
    {
        $data = [
            'prodList'   => $skuNos,
        ];
        $requestParam = [
            'method'    => 'queryStock',
            'data'      => $data
        ];
        $stockListRes=$this->execute($requestParam);
        if ($stockListRes['code']!=Normal::SUC){
            return Normal::returnCode(Normal::SUC,'获取库存成功',[]);
        }
        return Normal::returnCode(Normal::SUC,'获取库存成功',array_column($stockListRes['data']['rs'],'availQTY','PROD'));
    }

    /**
     * 创建订单
     */
    public function createOrder( $params = [] )
    {
        $orderInfo      = $params['supplierOrder'];
        $orderItem      = $params['orderGoods'];
        $order          = $params['order'];
        $binfo          = $params['binfo'];
        //支付流水号
        $pay_sn         = $order['paySerial'] ?? $orderInfo['pay_sn'];
        //运费
        $deliver_money  = $orderInfo['deliver_money'];
        //优惠
        $discount_money = $orderInfo['discount_money'] < 0 ? - $orderInfo['discount_money'] : $orderInfo['discount_money'] ;
        //下单支付的时候支付信息
        $apply_extends  = @json_decode($order['apply_extends'],true);
        //支付流水号
        $order_sn       = $orderInfo['supplier_dsn'];
        //组装商品数据列表
        $goodsList  = [];
        $goodsTotalMoney = $TotalTax = 0;
        foreach ($orderItem as $key=>$item )
        {

            $tax_rate           = bcadd('1', (string)$item['tax_rate'],4);
            //售价
            $price              = $item['price'];
            $spec_num           = $item['spec_num'];
            $quantity           = $item['quantity'];
            $supplier_skucode   = $item['supplier_skucode'];

            if ($key==0){
                $singerDeliverMoney=bcdiv($deliver_money,$quantity,3);
                $singerDeliverMoney=ceil((float)bcmul($singerDeliverMoney,100,1));
                $singerDeliverMoney=bcdiv($singerDeliverMoney,100,2);
                $price=bcadd($price,$singerDeliverMoney,2);
            }

            //商品不含税价格
            $goodsPrice         = bcdiv((string)$price, $tax_rate,2);
            $goodsCustomsTax    = bcsub((string)$price,$goodsPrice,2);
            $goodsCustomsTax    = bcmul($goodsCustomsTax,$quantity,2);
            $TotalTax           = bcadd((string)$TotalTax,$goodsCustomsTax,2);
            //购买总数量
            $goodsTotalPrice    = bcmul($goodsPrice,(string)$quantity,2);
            $goodsInfo = [
                'SITE_NAME'                 => $this->clientConfig['site_name'],
                'CUSTSNAME'                 => $this->clientConfig['custsname'],
                'ORDNO'                     => $order_sn,
                'PROD'                      => $supplier_skucode,
                'REQ_SUPP'                  => $this->clientConfig['req_supp'],
                'REQ_QTY'                   => $quantity,//购买数量
                'SBDJ'                      => $goodsPrice,//渠道售价(包装规格单价,如package_num = 2,此字段表示的是以包装规格为2件计算的单价，单位：元，保留两位小数)
                'SPECCOUNT'                 => $spec_num,//包装规格【如无匹配包装规格可传0，生成订单的包装规格会按下单数量/包装规格，取最大能除尽的规格】
            ];
            $goodsList[]=$goodsInfo;
            $goodsTotalMoney    = bcadd((string)$goodsTotalMoney,$goodsTotalPrice,2);
        }
        //订单优惠金额
        $real_total_money       = $orderInfo['real_total_money'];
        //商品类型
        $goods_type             = current($orderItem)['goods_type'];

        //创建订单数据
        $data = [
            'SITE_NAME'                	=> $this->clientConfig['site_name'],
            'CUSTSNAME'                	=> $this->clientConfig['custsname'],
            'ORDNO'           	        => $order_sn,
            'PT_ORDNO'     	            => $order_sn,
            'ORDNO_TYPE'            	=> $goods_type == 1 ? 'B' : 'Z',
            'SUPPSNAME'                 => $this->clientConfig['suppsname'],
            'DSNAME'                    => $this->clientConfig['req_supp'],
            'SHDW'              	    => $order['enterpriseName']??$apply_extends['enterpriseName']??'',
            'DSCODE'              	    => $order['enterpriseNum']??$apply_extends['enterpriseNum']??'',
            'ZFDH'                      => $pay_sn,
            'ZFPTBH'                    => $order['payCommanyCode']??$apply_extends['payCommanyCode'],
            'DDZJE'                     => $real_total_money,
            'CJZJ'                      => $real_total_money,
            'DDHK'                      => $goodsTotalMoney,
            'DDSE'                      => $TotalTax,
            'DDBF'                      => 0.00,
            'YF'                        => 0.00,
            'CJSJ'                      => date("Y-m-d H:i:s",time()),
            'ZFID'                      => $orderInfo['recveive_phone'],
            'ZFRXM'        	            => $orderInfo['buyer_realname'],
            'GMRSFZH'     	            => $orderInfo['buyer_idcard'],
            'SJRXM'                     => $orderInfo['receive_name'],
            'SJRLXFS'                   => $orderInfo['recveive_phone'],
            'SJRSHENG'        	        => $orderInfo['province'],
            'SJRSHI'            	    => $orderInfo['city'],
            'SJRQU'            	        => $orderInfo['district'],
            'SJRDZ'         	        => $orderInfo['receive_address'],
            'FJRXM'                     => $this->clientConfig['req_supp'],
            'YB'                        => '000001',
            'WMSID'                     => $this->clientConfig['wmsid'],
            'OUT_DET'                   => $goodsList
        ];
        return $this->execute([
            'method'=>'orderCreate',
            'data'=>$data
        ]);
    }

}
